<?php
namespace app\api\controller\v1;

use app\api\model\v1\Pen as PenModel;

/**
 * 电子围栏
 * 访问：/api/v1.pen/方法名；
 */
class Pen extends Base
{
    // 在redis 中存放 hash 值的 key；
    private $redisPenKey = 'pens';

    // 电子围栏
    // 设置电子围栏（坐标、半径、启用或暂停）添加和修改功能；
    public function setx() {
        try {
            $data = $this->jmParameter(['account_id', 'device_id', 'pen_id', 'address', 'longitude', 'latitude', 'radius', 'status']);
            $validateResult = $this->validate($data,
                $this->jmSetRule([
                    'device_id' => ['require', 'regex' => \jm\helper\Check::$regexpArray['id']],
                    'pen_id' => ['regex' => \jm\helper\Check::$regexpArray['id']],
                    'address' => 'require',
                    'longitude' => 'require',
                    'latitude' => 'require',
                    'radius' => 'require',
                    'status' => 'require|in:0,1'
                ]),
                $this->jmSetMessage([
                    'device_id.regex' => '设备ID无效',
                    'pen_id.regex' => '电子围栏ID无效'
                ])
            );

            if (true !== $validateResult) {
                return json([
                    'errcode' => 4001,
                    'message' => $validateResult
                ]);
            }
            
            // 当有 pen_id 时表示修改；
            $this->jmUnsetEmptyAndTrans2int($data, ['account_id', 'device_id', 'pen_id']);
            
            // 表示修改
            if (isset($data['pen_id'])) {
                $model = PenModel::field(['id', 'device_id'])->where([
                    'id' => $data['pen_id'],
                    'device_id' => $data['device_id']
                ])->find();
                if (is_null($model)) {
                    return json([
                        'errcode' => 4002,
                        'message' => '该电子围栏不存在'
                    ]);
                }
            } else {
                // 表示新增
                $model = new PenModel();
                $model->device_id = $data['device_id'];
                $imei = $this->jmGetIMEI($data['device_id']);
                $model->name = (is_null($imei) ? $data['device_id'] : $imei) . '的电子围栏';
            }

            $model->address = $data['address'];
            $model->longitude = $data['longitude'];
            $model->latitude = $data['latitude'];
            $model->radius = $data['radius'];
            $model->status = $data['status'];
            $model->jpush_status = '0';// 重置；
            $model->save();

            // 在 redis 中存放当前设备启用的电子围栏
            if ((1 * $data['status']) === 1) {
                $model->user_id = $data['account_id'];
                $redisRes = $this->_pen2redis($data['device_id'], $model);
            } else {
                $redisRes = $this->_penClearRedis($data['device_id'], $model);
            }

            return json([
                'errcode' => 200,
                'message' => '设置成功',
                'data' => [
                    'pen_id' => $model->id
                ]
            ]);
        } catch (\Exception $e) {
            return $this->jmException($e);
        }
    }

    // 返回电子围栏
    public function getx() {
        try {
            $data = $this->jmParameter(['account_id', 'device_id']);
            $validateResult = $this->validate($data,
                $this->jmSetRule(['device_id' => ['regex' => \jm\helper\Check::$regexpArray['id']],]),
                $this->jmSetMessage(['device_id.regex' => '设备ID无效'])
            );

            if (true !== $validateResult) {
                return json([
                    'errcode' => 4001,
                    'message' => $validateResult
                ]);
            }

            $model = PenModel::field(['id', 'address', 'longitude', 'latitude', 'radius', 'status'])
                ->where('device_id', $data['device_id'])->find();

            // 当不存在时，说明第一次调用该接口；
            if (is_null($model)) {
                $model = new PenModel();
                $model->address = '';
                $model->longitude = 0.0;
                $model->latitude = 0.0;
                $model->radius = 100;
                $model->status = '0';

                // 表里还没有数据时，表示之前还没有设置过电子围栏，此时获取设备的当前位置；
                $res = $this->jmGetGPS($data['device_id']);
                if ($res['errcode'] === 200) {
                    if (!is_null($res['data'])) {
                        $model->address = $res['data']['device_address'];
                        $model->longitude = $res['data']['device_latlng'][0];
                        $model->latitude = $res['data']['device_latlng'][1];
                    }
                } else {
                    return json([
                        'errcode' => 4002, 
                        'message' => '获取电子围栏数据失败'
                    ]);
                }
            }

            // 半径的最大最小值
            // $model->radius_range = [100, 1000];
            $model->radius_range = \think\Config::get('pen.radius');

            return json([
                'errcode' => 200, 
                'message' => '获取电子围栏数据成功',
                'data' => $model
            ]);

        } catch (\Exception $e) {
            return $this->jmException($e);
        }
    }

    // 将启用的电子围栏存放到redis中
    private function _pen2redis($deviceId, $model) {
        try {
            $imei = $this->jmGetIMEI($deviceId);
            $redis = \jm\helper\Db::getRedisIns();
            // 成功返回 int(1)
            $res = $redis->hset($this->redisPenKey, $imei, json_encode([
                'pen_id' => $model->id,
                'pen_device_id' => $model->device_id,
                'pen_user_id' => $model->user_id,
                'pen_name' => urlencode($model->name),
                'pen_type' => 1,
                'address' => $model->address,
                'pen_center' => [$model->longitude, $model->latitude],
                'pen_radius' => $model->radius,
                'pen_date' => $model->updated_at
            ]));
            if ($res) {
                return ['errcode'=>200, 'message'=>'电子围栏存放redis成功'];
            } else {
                return ['errcode'=>4001, 'message'=>'电子围栏存放redis失败'];
            }
        } catch (\Exception $e) {
            return $this->jmException($e, false);
        }
    }

    // 将启用的电子围栏从redis中清除
    private function _penClearRedis($deviceId, $model) {
        try {
            $imei = $this->jmGetIMEI($deviceId);
            $redis = \jm\helper\Db::getRedisIns();
            
            // 成功返回 int(1)
            $res = $redis->hdel($this->redisPenKey, $imei);
            if ($res) {
                return ['errcode'=>200, 'message'=>'电子围栏从redis清除成功'];
            } else {
                return ['errcode'=>4001, 'message'=>'电子围栏从redis清除失败'];
            }
        } catch (\Exception $e) {
            return $this->jmException($e, false);
        }
    }
}